package com.Jano.servlet;

import com.Jano.dto.FriendDto;
import com.Jano.dto.UserDto;
import com.Jano.entity.User;
import com.Jano.exception.BusinessException;
import com.Jano.service.Impl.UserServiceImpl;
import com.Jano.service.UserService;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static com.Jano.constant.BusinessConstant.*;
import static com.Jano.constant.BusinessConstant.REDIS_PRODUCT_KEY;

/**
 * description: UserServlet <br>
 * date: 2022/6/10 5:22 PM <br>
 * author: zoumaoji <br>
 * version: 1.0 <br>
 */
@WebServlet(urlPatterns = "/apis/users/*")
public class UserServlet extends AbstractBaseServlet {
    UserService userService = new UserServiceImpl();

    /**
     * 返回不重复的序列号
     *
     * @return
     */
    private String generateToken() {
        return UUID.randomUUID().toString();
    }

    @Override
    public Object doService(String action, HttpServletRequest req, HttpServletResponse res) throws UnsupportedEncodingException {
        //自动登录操作
        if ("autoLogin".equals(action)) {
            String cookieUserInfo = getCookie(req, COOKIE_USER_NAME);
            //将Cookie中的用户信息交给Service处理，看是否能够完成自动登录
            //如果可以在返回用户信息并在Session中设置用户信息
            User user = userService.autoLogin(cookieUserInfo);
            if (Objects.nonNull(user)) {
                //密码脱敏
                user.setPassWord(null);
                setSessionAttribute(req, COOKIE_USER_NAME, user);
            }
            return user;
        }

        //手动登陆操作
        if ("login".equals(action)) {
            //用户填写的名字
            String userName = req.getParameter("userName");
            //用户填写的密码
            String passWord = req.getParameter("userPwd");
            User userLogin = userService.login(userName, passWord);
            //登陆成功
            //密码需要脱敏
            UserDto userDto = UserDto.builder()
                    .userId(userLogin.getUserId())
                    .userName(userLogin.getUserName())
                    .phone(userLogin.getPhone())
                    .singNature(userLogin.getSingNature())
                    .hobbies(userLogin.getHobbies())
                    .address(userLogin.getAddress())
                    .build();
            //Session持久化（结合Session的工作原理，通过Redis取代Session在服务器端保存当前登录用户的信息）
            try (JedisPool jedisPool = new JedisPool(REDIS_HOST, REDIS_POST);
                 Jedis jedis = jedisPool.getResource()) {
                // 随机生成token,作为登录令牌
                String token = generateToken();
                String redisKey = LOGIN_USER_KEY + token;
                //获取session 将key存储到SESSION当中
                setSessionAttribute(req, SESSION_USER_KEY, redisKey);
                //将userDto存入redis
                jedis.set(redisKey, JSON.toJSONString(userDto));
            }
            // 防止""
            if (StringUtils.isBlank(req.getParameter("selected"))) {
                return userDto;
            }
            //判断免登陆框是否选择 实现自动登录
            if (IS_Selected.equals(req.getParameter("selected"))) {
                setCookie(res, COOKIE_USER_NAME, DigestUtils.md5Hex(userLogin.getUserName() + "," + userLogin.getPassWord()), COOKIE_USER_NAME_MAX_AGE);
            }
            return userDto;
        }

        //通过token作为key在redis中获取当前登录用户
        if ("getLoginUser".equals(action)) {
            try (JedisPool jedisPool = new JedisPool(REDIS_HOST, REDIS_POST);
                 Jedis jedis = jedisPool.getResource()) {
                String attribute = (String) req.getSession().getAttribute(SESSION_USER_KEY);
                System.out.println("拿到的redisKey" + req.getSession().getAttribute(SESSION_USER_KEY));
                if (StringUtils.isBlank(attribute)) {
                    throw new BusinessException("当前用户尚未登录");
                }
                UserDto userDto = JSON.parseObject(jedis.get(attribute), UserDto.class);
                if (Objects.isNull(userDto)) {
                    throw new BusinessException("当前用户尚未登录");
                } else {
                    return userDto;
                }
            }
        }

        //注册操作
        if ("register".equals(action)) {
            String userName = req.getParameter("userName");
            String passWord = req.getParameter("passWord");
            String pwdConfirm = req.getParameter("pwdConfirm");
            userService.register(userName, passWord, pwdConfirm);
        }

        //查看两个用户之间的共同好友 mysql实现
        if ("commonFriends".equals(action)) {
            List<FriendDto> commonFriendDto = userService.getCommonFriendsIdByUserId(paramToInt(req, "firstUserId"), paramToInt(req, "secondUserId"));
            if (commonFriendDto.isEmpty()) {
                throw new BusinessException("没有共同好友");
            } else {
                return commonFriendDto;
            }
        }
        //TODO redis集合操作实现

        //注销操作
        if ("logout".equals(action)) {
            try (JedisPool jedisPool = new JedisPool(REDIS_HOST, REDIS_POST);
                 Jedis jedis = jedisPool.getResource()) {
                // 删除redis的key
                jedis.del((String) req.getSession().getAttribute(SESSION_USER_KEY));
                //移除Session
                req.getSession().invalidate();
                //移除Cookie
                Cookie[] cookies = req.getCookies();
                if (ArrayUtils.isEmpty(cookies)) {
                    System.err.println("当前没有任何Cookie信息");
                } else {
                    for (Cookie c : cookies) {
                        if (StringUtils.equals(c.getName(), "user")) {
                            //⚠️注意‼️‼️：将Cookie的生命周期设置为0，相当于就是删除Cookie
                            c.setMaxAge(0);
                            //⚠️‼️这里如果不设置路径，可能无法删除 cookie被忽略
                            c.setPath("/");
                            //修改后的Cookie对象要写回客户端覆盖原来的Cookie
                            res.addCookie(c);
                            break;
                        }
                    }
                }
            }
        }
        return null;
    }

    @Test
    public void test() {
        System.out.println(StringUtils.equals("", "1"));
    }
}
